//
//  AFFDataText.m
//  AnyfishApp
//
//  Created by bob on 14-8-25.
//  Copyright (c) 2014年 Anyfish. All rights reserved.
//

#import "AFFDataText.h"






static NSMutableArray *mArrCacheName; ///< 缓存名称：人名称
static NSMutableArray *mArrCacheNameNote; ///< 缓存名称：好友备注
static NSMutableArray *mArrCacheNameWorker; ///< 缓存名称：职员名称
static NSMutableArray *mArrCacheNameNickRoom; ///< 缓存名称：群昵称
static NSMutableArray *mArrCacheImage; ///< 缓存头像[{"code":image}]



static NSMutableArray *mArrCacheSeal; ///< 缓存名称：鱼章数据，进入详情页尝试更新
static NSMutableArray *mArrCacheSealSigned; ///< 缓存数据：我贴了的人的信息code，章类型，星期几
static NSMutableArray *mArrCacheNameRoom; ///< 缓存名称：群、商家、等其他五素

@implementation AFFDataPartion

- (id)init {
    self = [super init];
    if(self){
        //        self.color = kSetting.color_666666;
    }
    
    return self;
}

- (BOOL)isEqual:(id)object {
    if([super isEqual:object])return YES;
    
    if([object isKindOfClass:[AFFDataPartion class]]){
        AFFDataPartion *partion = (AFFDataPartion*)object;
        
        return partion.type==_type &&
                partion.code==_code &&
                partion.code2 == _code2 &&
                partion.elementCode==_elementCode;
    }
    
    return NO;
}

- (id)copySelf{
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.type = _type;
    partion.code = _code;
    partion.code2 = _code2;
    partion.range = _range;
    partion.textShow = _textShow;
    partion.textDecode = _textDecode;
    partion.color = _color;
    partion.textTag = _textTag;
    partion.fontSize = _fontSize;
    partion.textConfig = _textConfig;
    partion.elementCode = _elementCode;
    partion.isReplaced = _isReplaced;
    partion.hasIcon = _hasIcon;
    partion.needPull = _needPull;
    partion.showEmptySeal = _showEmptySeal;
    
    return partion;
}

- (NSString*)textShow {
    if(_textShow)
        return _textShow;
    
    return [NSString stringWithFormat:@"%lld", _code];
}

- (U8)afType {

    return 0;
}




- (void)setDataIcon:(NSData *)dataIcon {
    _dataIcon = dataIcon;
    _hasIcon = YES;
}

- (NSString*)imageName {
    return [NSString stringWithFormat:@"%@/%lld_%d.png", kSetting.path_Download, self.code, [AFFDataText getCachePartionType:self isName:NO]];
}

- (BOOL)saveIcon {
    NSError *error;
    if(self.dataIcon){

        [self.dataIcon writeToFile:self.imageName options:NSDataWritingAtomic error:&error];
    }
    
    if(error){
        NSLog(@"图片获取,保存头像出错：%@", error);
    }
    
    return error==nil;
}



+ (BOOL)cacheIcon:(AFEPartionType)type {
    if(type == kPartionTypeStreetProduct ||
       type == kPartionTypeStreetBate ||
       type == kPartionTypeGMTBao ||
       type == kPartionTypeRoom){
        return NO;
    }
    
    return YES;
}

@end

@interface AFFDataText()

@end

@implementation AFFDataText

+ (AFFDataText*)initWithDataText:(AFFDataText*)dataText {
    AFFDataText *text = [[AFFDataText alloc] init];
    [text addDataText:dataText];
    text.hideSpecial = dataText.hideSpecial;
    text.hideAllSpecial = dataText.hideAllSpecial;
    text.showPrex = dataText.showPrex;
    text.font = dataText.font;
    text.color = dataText.color;
    text.numberOfline = dataText.numberOfline;
    text.showNameType = dataText.showNameType;
    text.parseType = dataText.parseType;
    text.imgStyle = dataText.imgStyle;
    text.getType = dataText.getType;
    text.dataPulled = dataText.dataPulled;
    
    AFFDataPartion *partion = nil;
    for(AFFDataPartion *pa in dataText.array){
        if(pa.code>0){
            partion = pa;
            break;
        }
    }
    
    if(partion){
        if(dataText.imgSet){
            text.imgSet = dataText.imgSet;
        }
    }
    
    return text;
}

- (id)initWithText:(NSString*)text {
    self = [self init];
    if(self){
        [self addText:text];
    }
    
    return self;
}

- (id)initWithText:(NSString*)text color:(UIColor*)color {
    self = [self init];
    if(self){
        [self addText:text color:color];
    }
    
    return self;
}

- (id)initWithCode:(U64)code text:(NSString*)text {
    self = [self init];
    if(self){
        [self addCode:code text:text];
    }
    
    return self;
}

- (id)initWithCode:(U64)code text:(NSString*)text color:(UIColor*)color {
    self = [self init];
    if(self){
        [self addCode:code text:text color:color];
    }
    
    return self;
}

- (id)initWithCode:(U64)code pType:(AFEPartionType)pType eleCode:(U64)eleCode text:(NSString*)text {
    self = [self init];
    if(self){
        [self addCode:code pType:pType eleCode:eleCode text:text];
    }
    
    return self;
}

- (id)initWithCode:(U64)code pType:(AFEPartionType)pType eleCode:(U64)eleCode text:(NSString*)text color:(UIColor*)color {
    self = [self init];
    if(self){
        [self addCode:code pType:pType eleCode:eleCode text:text color:color];
    }
    
    return self;
}

- (void)encodeWithCoder: (NSCoder *)coder {
    [coder encodeObject:_array forKey:@"array"];
}

- (id)initWithCoder: (NSCoder *)coder {
    self = [[AFFDataText alloc] init];
    
    if (self)
    {
        _array = [coder decodeObjectForKey:@"array"];
    }
    
    return self;
}

- (instancetype)init {
    self = [super init];
    
    if (self)
    {
        _array = [NSMutableArray array];
        _mArrRichTextRuns = [NSMutableArray array];
        _mDicRichTextRunRect = [NSMutableDictionary dictionary];
        _parseType = ERichTextType;
        _parseExp = YES;
        //        _isAutoPlay = YES;
        _deltaTime = kRichPlayDelay_Common;
        _numberOfline = 1;
        _showNameType = EPlayerShow_NoteNameFirst;
        _imgStyle = EImageStyle_Thumb;
        _getType = EDataGet_LocalOrServer;
        
        _color = kSetting.color_Text;
        _font = kSetting.font_Text;
    }
    
    return self;
}

- (id)copyWithZone:(NSZone*)zone {
    AFFDataText * msgText = [[[self class] allocWithZone:zone] init];
    
    return msgText;
}

- (void)dealloc {
    [_array removeAllObjects]; _array = nil;
    
    _dataPulled = nil;
    _imgSet = nil;
    _font = nil;
    _color = nil;
    if(_attLabel)
        [_attLabel removeFromSuperview];
    _attLabel = nil;
    _attString = nil;
    [_mArrRichTextRuns removeAllObjects]; _mArrRichTextRuns = nil;
    [_mDicRichTextRunRect removeAllObjects]; _mDicRichTextRunRect = nil;
    _textAnalyzed = nil;
}

- (AFFDataPartion*)partionWithIndex:(NSInteger)index {
    return [self.array objectWithIndex:index];
}

- (AFFDataPartion*)partionWithCode {
    AFFDataPartion *partion = nil;
    for(AFFDataPartion *pa in _array){
        if(pa.code>0){
            partion = pa;
            break;
        }
    }
    
    return partion;
}

- (AFFDataPartion*)partionLast {
    return [_array lastObject];
}

#pragma mark 属性变化设置

// 注意需要用到这个属性的类型需要在这里确认是否调用准确了
- (U32)imgDlType {
    AFFDataPartion *partion = nil;
    for(AFFDataPartion *pa in _array){
        if(pa.code>0){
            partion = pa;
            break;
        }
    }
    
    if(partion) {
        U32 dType = 0;
        AFFDataPartion *partion = nil;
        for(AFFDataPartion *pa in _array){
            if(pa.code>0){
                partion = pa;
                break;
            }
        }
        
        if(partion) {
            switch (partion.type) {
                case 0:
                    dType = 0;
                    break;
                    
                default:
                    break;
            }
        }
        
        return dType;
    }
    
    return 0;
}

- (BOOL)isEmpty {
    return _array.count==0;
}

- (void)setColor:(UIColor *)color {
    _color = color;
}

- (void)setFont:(UIFont *)font {
    _font = font;
}

- (void)setTextAlignment:(NSTextAlignment)textAlignment {
    _textAlignment = textAlignment;
}

- (CGFloat)lineSpace {
    if(_lineSpace>0)
        return _lineSpace;
    
    CGFloat space = 4.0;
    // 以聊天气泡文字为准 16号
    CGFloat delta = _font.pointSize / kSetting.font_Chat_Title.pointSize;
    return space*delta;
}

- (CGFloat)widthSupport {
    return self.rFrame.size.width>0?self.rFrame.size.width:_widthUsed>0?_widthUsed:10;
}

- (void)setRFrame:(CGRect)rFrame{
    if(rFrame.size.width<0 || rFrame.size.height<0){
        NSLog(@"****ERROR*** %@ AFFRichTextView 怎么出现绘制范围<0情况：width-%f,height-%f",self,rFrame.size.width,rFrame.size.height);
    }
    
    _original = rFrame.origin;
    _widthSupport = fabs(rFrame.size.width);
    _heightSupport = fabs(rFrame.size.height);
}

- (CGRect)rFrame{
    return CGRectMake(_original.x, _original.y+(_heightSupport>_heightUsed?(_heightSupport-_heightUsed)/2:0), _widthSupport, _heightSupport);
}

- (CGSize)sizeUsed {
    return CGSizeMake(_widthUsed, _heightUsed);
}

- (BOOL)isNeedMorelines {
    return _numberOfline<_numberOflineDrawed;
}

- (BOOL)hadAnalyzed {
    return _attString!=nil;
}

- (void)setImageIcon:(UIImage *)imageIcon {
    _imgSet = imageIcon;
}



- (UIImage*)getDefaultImage:(NSString*)imageName partion:(AFFDataPartion*)partion{
    if(imageName==nil)
        return nil;
    
    UIImage *img = nil;
    
    NSString *tag = nil;
    switch (_iconSize) {
        case EIconSize_58: { tag = @"58"; } break;
        case EIconSize_72: { tag = @"72"; } break;
        case EIconSize_80: { tag = @"80"; } break;
        case EIconSize_100: { tag = @"100"; } break;
        case EIconSize_108: { tag = @"108"; } break;
        case EIconSize_118: { tag = @"118"; } break;
        case EIconSize_144: { tag = @"144"; } break;
        case EIconSize_154: { tag = @"154"; } break;
        case EIconSize_298: { tag = @"298"; } break;
            
        default:
            break;
    }
    
    if(tag){
        NSString *imgName = [NSString stringWithFormat:@"%@_%@", imageName, tag];
        img = [UIImage imageNamed:imgName];
    }
    
    if(img==nil){
        img = [UIImage imageNamed:imageName];
    }
    
    return img;
}

- (U64)dataCode {
    if(_array.count==0)
        return 0;
    
    for(AFFDataPartion *partion in _array){
        if(partion.code>0){
            return partion.code;
        }
    }
    
    return 0;
}

- (BOOL)hideSpecial {
    if(_hideAllSpecial)
        return YES;
    
    for(AFFDataPartion *partion in _array){
        if(partion.color || partion.fontSize>0 || partion.font){
            return NO;
        }
    }
    
    // 特殊处理链接
    if(_mArrRichTextRuns>0){
        for(AFFRichTextBase *rich in _mArrRichTextRuns){
            if([rich isKindOfClass:[AFFRichTextHtml class]] ||
               [rich isKindOfClass:[AFFRichTextNumber class]]){
                return NO;
            }
        }
    }
    
    return _color==nil||_font==nil; // 只要用户有设置过就算不隐藏
}

#pragma mark End

- (void)insertText:(NSString*)text {
    [self insertText:text color:nil];
}

- (void)insertText:(NSString*)text color:(UIColor*)color{
    if([NSString isNilOrEmpty:text])
        return;
    
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = kPartionTypeText;
    
    partion.textShow = text;
    
    partion.textDecode = text;
    if(color)
        partion.color = color;
    
    [_array insertObject:partion atIndex:0];
}

- (void)addText:(NSString*)text {
    [self addText:text color:nil];
}

- (void)addText:(NSString*)text color:(UIColor*)color{
    if([NSString isNilOrEmpty:text])
        return;
    
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = kPartionTypeText;
    
    partion.textShow = text;
    
    partion.textDecode = text;
    if(color)
        partion.color = color;
    [_array addObject:partion];
}



#pragma mark 直接指定类型

- (void)addCode:(U64)code pType:(AFEPartionType)pType eleCode:(U64)eleCode text:(NSString*)text {
    [self addCode:code pType:pType eleCode:eleCode text:text color:nil];
}

- (void)addCode:(U64)code pType:(AFEPartionType)pType eleCode:(U64)eleCode text:(NSString*)text color:(UIColor*)color {
    if(eleCode>0)
        _elementCode = eleCode;
    
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = pType;
    partion.code = code;
    partion.elementCode = eleCode;
    if(color)
        partion.color = color;
    
    if([NSString isNilOrEmpty:text])
    {
        if([NSString isNilOrEmpty:partion.textDecode]){
//            if(partion.type == kPartionTypeLand){
//                partion.textShow = @"正在获取地名...";
//            }else {
                if([NSString isNilOrEmpty:partion.textShow]){
                    partion.textShow = [NSString stringWithFormat:@"%lld",code];
                }
//            }
        }
    }
    else
    {
        partion.textShow = text;
        
        partion.textDecode = text;
    }
    
    [_array addObject:partion];
}

#pragma mark 5素或有明确百鱼类型的code

- (void)addCode:(U64)code text:(NSString*)text {
    [self addCode:code text:text color:nil];
}

- (void)addCode:(U64)code text:(NSString*)text color:(UIColor*)color {
    AFEPartionType pType = [AFFDataText getTypeFromCode:code];
    [self addCode:code pType:pType eleCode:0 text:text color:color];
}

#pragma mark - 定位

- (void)addCodeLand:(U64)code text:(NSString*)text {
    [self addCodeLand:code text:text color:nil];
}

- (void)addCodeLand:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypeLand eleCode:0 text:text color:color];
}

- (void)addLocationLon:(S32)longtitude lat:(S32)latitude text:(NSString*)text{
    [self addLocationLon:longtitude lat:latitude text:text color:nil];
}

- (void)addLocationLon:(S32)longtitude lat:(S32)latitude needDetail:(BOOL)needDetail text:(NSString *)text{
    [self addLocationLon:longtitude lat:latitude needDetail:needDetail text:text color:nil];
}

- (void)addLocationLon:(S32)longtitude lat:(S32)latitude text:(NSString *)text color:(UIColor *)color{
    [self addLocationLon:longtitude lat:latitude needDetail:YES text:text color:color];
}



#pragma mark 鱼

- (void)addFish:(U64)type text:(NSString*)text {
    [self addFish:type text:text color:nil];
}

- (void)addFish:(U64)type text:(NSString*)text color:(UIColor*)color {
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = kPartionTypeProduct;
    partion.code = type;
    if(color)
        partion.color = color;
    
    if([NSString isNilOrEmpty:text])
    {
        if([NSString isNilOrEmpty:partion.textDecode]){
            partion.textShow = @"鱼";
        }
    }
    else
    {
        partion.textShow = text;
        partion.textDecode = text;
    }
    
    [_array addObject:partion];
}

#pragma mark 鱼章

- (void)addFishSeal:(U64)code text:(NSString*)text {
    [self addFishSeal:code text:text color:nil];
}

- (void)addFishSeal:(U64)type text:(NSString*)text color:(UIColor*)color {
    [self addCode:type pType:kPartionTypeSeal eleCode:0 text:text color:color];
}

#pragma mark 商家船

- (void)addEntitySeal:(U64)code text:(NSString*)text {
    [self addEntitySeal:code text:text color:nil];
}

- (void)addEntitySeal:(U64)type text:(NSString*)text color:(UIColor*)color {
    [self addCode:type pType:kPartionTypeEntitySeal eleCode:0 text:text color:color];
}

#pragma mark 公司

- (void)addCodeCompany:(U64)code text:(NSString*)text {
    [self addCodeCompany:code text:text color:nil];
}

- (void)addCodeCompany:(U64)code text:(NSString*)text color:(UIColor*)color {
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = kPartionTypeCompany;
    partion.code = code;
    if(color)
        partion.color = color;
    
    if(partion.afType == 1){
        [self addCode:code text:text color:color];
        return;
    }
    
    if([NSString isNilOrEmpty:text])
    {
    }
    else
    {
        partion.textShow = text;
        
        partion.textDecode = text;
    }
    
    [_array addObject:partion];
}

- (void)addCodeWorkRole:(U64)code role:(U32)role {
    [self addCodeWorkRole:code role:role color:nil];
}

- (void)addCodeWorkRole:(U64)code role:(U32)role color:(UIColor*)color {
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = kPartionTypeWorkRole;
    partion.code = code;
    partion.code2 = role;
    if(color)
        partion.color = color;
    

    [_array addObject:partion];
}

#pragma mark 鱼报

- (void)addCodePaper:(U64)code text:(NSString*)text {
    [self addCodePaper:code text:text color:nil];
}

- (void)addCodePaper:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypePaper eleCode:0 text:text color:color];
}

#pragma mark 社区

- (void)addCodeLive:(U64)code text:(NSString*)text {
    [self addCodeLive:code text:text color:nil];
}

- (void)addCodeLive:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypeLand eleCode:0 text:text color:color];
}

#pragma mark 街巷

- (void)addCodeStreet:(U64)code text:(NSString*)text {
    [self addCodeStreet:code text:text color:nil];
}

- (void)addCodeStreet:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypeStreet eleCode:0 text:text color:color];
}

#pragma mark 后街商品

- (void)addCodeBate:(U64)code text:(NSString*)text {
    [self addCodeBate:code text:text color:nil];
}

- (void)addCodeBate:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypeStreetBate eleCode:0 text:text color:color];
}

#pragma mark 商圈信息

- (void)addCodeGMCircle:(U64)code text:(NSString*)text {
    [self addCodeGMCircle:code text:text color:nil];
}

- (void)addCodeGMCircle:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypeGMCircle eleCode:0 text:text color:color];
}

#pragma mark 淘宝客商品

- (void)addCodeGMTBao:(U64)code text:(NSString*)text {
    [self addCodeGMTBao:code text:text color:nil];
}

- (void)addCodeGMTBao:(U64)code text:(NSString*)text color:(UIColor*)color {
    [self addCode:code pType:kPartionTypeGMTBao eleCode:0 text:text color:color];
}

#pragma mark 特殊组合

- (BOOL)isSpecialView {
    // TODO:使用最新富文本绘制
//    return YES;
    
    for(AFFDataPartion *partion in _array){
        if(partion.type==kPartionTypeC_View ||
           partion.type==kPartionTypeC_Button ||
           partion.type==kPartionTypeC_Image ||
           partion.type==kPartionTypeC_Label ||
           partion.type==kPartionTypeC_Text){
            return YES;
        }
    }
    
    return NO;
}

- (void)addTextEx:(NSString *)text {
    [self addTextEx:text txtColor:nil];
}

- (void)addTextEx:(NSString *)text txtColor:(UIColor*)txtColor {
    if([NSString isNilOrEmpty:text])
        return;
    
    AFFDataPartion * partion = [[AFFDataPartion alloc] init];
    
    partion.type = kPartionTypeText;
    
    partion.textShow = text;
    
    partion.textDecode = text;
    if(txtColor)
        partion.color = txtColor;
    [_array addObject:partion];
}

- (void)addView:(UIView*)view {
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.type = kPartionTypeC_View;
    partion.view = view;
    partion.textDecode = [NSString stringWithFormat:@"[view%lld]", [NSDate timeMicro]];
    
    [_array addObject:partion];
}

- (void)addButton:(NSInteger)tag title:(NSString*)title txtColor:(UIColor*)txtColor font:(UIFont*)font bgColor:(UIColor*)bgColor corner:(CGFloat)corner  borderColor:(UIColor*)borderColor borderWidth:(CGFloat)borderWidth {
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.type = kPartionTypeC_Button;
    partion.tag = tag;
    partion.containTitle = title;
    partion.color = txtColor;
    partion.colorBg = bgColor;
    partion.corner = corner;
    partion.font = font;
    partion.borderWidth = borderWidth;
    partion.colorBorder = borderColor;
    partion.textDecode = [NSString stringWithFormat:@"[button%lld]", [NSDate timeMicro]];
    
    [_array addObject:partion];
}

- (void)addButton:(NSInteger)tag title:(NSString*)title txtColor:(UIColor*)txtColor font:(UIFont*)font bgColor:(UIColor*)bgColor corner:(CGFloat)corner {
    [self addButton:tag title:title txtColor:txtColor font:font bgColor:bgColor corner:corner borderColor:nil borderWidth:0];
}

- (void)addLabel:(NSInteger)tag title:(NSString*)title txtColor:(UIColor*)txtColor font:(UIFont*)font bgColor:(UIColor*)bgColor corner:(float)corner borderColor:(UIColor*)borderColor borderWidth:(CGFloat)borderWidth {
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.type = kPartionTypeC_Label;
    partion.containTitle = title;
    partion.color = txtColor;
    partion.colorBg = bgColor;
    partion.corner = corner;
    partion.font = font;
    partion.borderWidth = borderWidth;
    partion.colorBorder = borderColor;
    partion.textDecode = [NSString stringWithFormat:@"[label%lld]", [NSDate timeMicro]];
    
    [_array addObject:partion];
}

- (void)addLabel:(NSInteger)tag title:(NSString*)title txtColor:(UIColor*)txtColor font:(UIFont*)font bgColor:(UIColor*)bgColor corner:(float)corner {
    [self addLabel:tag title:title txtColor:txtColor font:font bgColor:bgColor corner:corner borderColor:nil borderWidth:0];
}

- (void)addImage:(NSString*)imgName {
    [self addImage:imgName size:CGSizeZero];
}

- (void)addImage:(NSString*)imgName size:(CGSize)size {
    [self addImage:imgName size:size alignment:1];
}

- (void)addImage:(NSString*)imgName size:(CGSize)size alignment:(U8)alignment {
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.type = kPartionTypeC_Image;
    partion.imgName = imgName;
    partion.alignment = alignment;
    partion.size = size;
    partion.textDecode = [NSString stringWithFormat:@"[image%lld]", [NSDate timeMicro]];
    
    [_array addObject:partion];
}

#pragma mark 拉取控制逻辑

// 很多数据展示时候需要尝试检查内存是否已经获取到了，因为很多情况下组合数据时还没获取到，准备显示时数据已经缓存了
- (void)checkDataPulled {
    for(AFFDataPartion *partion in _array){
        if(partion.code>0 && partion.textDecode==nil){
        }
    }
}

// 清理计算的缓存
- (void)cleanPullTag {
    _widthSupport = 0;
    _widthUsed = 0;
    _attString = nil;
    _heightSupport = 0;
    _heightUsed = 0;
    _sizeUsed = CGSizeZero;
}

- (AFFDataPartion*)partion:(NSRange)range {
    for (AFFDataPartion *obj in _array)
    {
        if(NSLocationInRange(range.location,obj.range))
            return obj;
    }
    return nil;
}

- (NSString *)showText {
    return [self getDisplayText:NO];
}

- (NSString*)getDisplayText:(BOOL)isReplaced {
    NSMutableString *actionText = [[NSMutableString alloc]init];
    
    NSInteger nLoc=0;
    
    NSInteger nlen = 0;
    
    for (AFFDataPartion *obj in _array)
    {
        if(obj.isReplaced && isReplaced)
            continue;
        
        nLoc = actionText.length;
        
        if(obj.textDecode)
        {
            
            [actionText appendString:obj.textDecode];
            nlen = obj.textDecode.length;
        }
        else
        {
            [actionText appendString:obj.textShow];
            
            nlen = obj.textShow.length;
        }
        
        obj.range = NSMakeRange(nLoc, nlen);
    }
    
    return actionText;
}

- (NSString *)showNoPlaceText {
    return [self getDisplayText:YES];
}

- (void)removeAllText{
    [_array removeAllObjects];
    _attString = nil;
}

- (void)addTextPartion:(AFFDataPartion*)partion{
    if(_array && partion){
        [_array addObject:partion];
    }
}

- (void)addDataPartion:(AFFDataText*)dataText {
    if(dataText){
        for(AFFDataPartion *partion in dataText.array) {
            [_array addObject:partion];
        }
    }
}

- (void)addDataText:(AFFDataText*)dataText{
    if(dataText){
        for(AFFDataPartion *partion in dataText.array) {
            AFFDataPartion *partion1 = [partion copySelf];
            if(partion1)
                [_array addObject:partion1];
        }
    }
}

- (void)updateWithMsgText:(AFFDataText*)msgText{
    if(msgText){
        [_array removeAllObjects];
        [self addDataText:msgText];
    }
}

- (BOOL)needPullText {
    for (AFFDataPartion *obj in _array)
    {
        if(!obj.textDecode || obj.needPull) // 这里就不判断特殊类型了
        {
            return YES;
        }
    }
    
    return NO;
}





- (void)pullEnd:(BOOL)result block:(void (^)(BOOL result,id dataText))block {
    if(!result)return;
    
    if(!self.needPullText){
        if(block){
            WORK_MAIN(^{
                [NSTimer scheduledTimerWithTimeInterval:0.05 block:^{
                    _attString = nil; // 这里必须导致重新计算
                    block(result, self);
                } repeats:NO];
            });
        }
    }
}

- (void)pullEndIcon:(BOOL)result block:(void (^)(BOOL result,id dataText))block {
    if(!result)return;
    
    if(!self.needPullIcon){
        if(block){
            WORK_MAIN(^{
                [NSTimer scheduledTimerWithTimeInterval:0.05 block:^{
                    block(result, self);
                } repeats:NO];
            });
        }
    }
}

// 注意拉取其他名称都没获取到时采用，检查是否昵称有获取到
- (BOOL)checkNickName:(AFFDataPartion*)partion {
    if(partion.type == kPartionTypePlayer ||
       partion.type == kPartionTypePlayerNickName ||
       partion.type == kPartionTypePlayerRoomNickName ||
       partion.type == kPartionTypePlayerRoomWorkerName){
        
        AFFDataPartion *temp = [partion copySelf];
        temp.type = kPartionTypePlayer;
        
        if(![NSString isNilOrEmpty:temp.textDecode]){
            partion.textDecode = partion.textShow = temp.textDecode;
            return YES;
        }
    }
    
    return NO;
}

#pragma mark 帮助方法
- (void)pullDataIcon:(AFFDataPartion*)partion block:(void (^)(BOOL result,id dataText))block {
//    [AFFLAPIPublic getElementImage:partion.code getType:EDataGet_LocalOrServer dlType:self.imgDlType sign:NO imgStyle:_imgStyle back:YES block:^(AFFData *data, AFFDataError *error) {
//        BOOL result = NO;
//        if(data){
//            AFFDataPhoto *photo = (AFFDataPhoto*)data;
//            if(photo){
//                result = YES;
//                if(photo.imageData){
//                    self.imgSet = photo.image;
//
//                    // 群头像不支持本地缓存处理，因为不支持时时更新会有问题
//                    if(partion.type!=kPartionTypeRoom){
//                        partion.dataIcon = photo.imageData;
//                        [AFFDataText setCacheData:partion isName:NO];
//                    }
//                }else {
//                    partion.hasCheckIcon = YES;
//                }
//            }
//        }
//
//        block(result, self);
//    }];
}

// 拉取url链接的图片
- (void)pullDataIcon:(AFFDataPartion*)partion url:(NSString*)url block:(void (^)(BOOL result,id dataText))block  {
    if(![NSString isNilOrEmpty:url]){
        partion.textTag = url;
        // 这里必须缓存不然view会释放
        UIImageView *imgV = [[UIImageView alloc] init];
        partion.view = imgV;
        
//        [imgV sd_setImageWithURL:[[NSURL alloc] initWithString:url] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//            if(image){
//                // 最后决定还是不做缓存，因为同一个链接的图片可能对应code不同，会导致重复保存图片
//                _imgSet = image;
//                [self pullEndIcon:YES block:block];
//            }
//
//            partion.view = nil;
//        }];
    }
}


- (void)pullDataLocation:(AFFDataPartion*)partion block:(void (^)(BOOL result,id dataText))block {
    
    AFFLModeAddress *addr = [AFFLModeAddress getCacheAddress:(S32)partion.code lat:(S32)partion.code2];
    if(addr && ![NSString isNilOrEmpty:addr.desc]){
        partion.textDecode = partion.textShow = addr.desc;
        block(YES, self);
    }else {
        WORK_BACK(^{
            S32 lon = (S32)partion.code;
            S32 lat = (S32)partion.code2;
            
//            [CLLocationManager getLocationInfo:lon lat:lat block:^(CLPlacemark *placeMark) {
//                BOOL result = NO;
//                if(placeMark){
//                    partion.textDecode = partion.textShow = [CLLocationManager getLoactionAddr:placeMark];
//                    partion.textTag = [CLLocationManager getLocationGroup:placeMark];
//
//                    AFFLModeAddress *addr = [[AFFLModeAddress alloc] init];
//                    addr.longitude = lon;
//                    addr.latitude = lat;
//                    addr.landCode = partion.landCode;
//
//                    NSDictionary *dic = placeMark.addressDictionary;
//                    addr.desc = [dic stringForKey:@"Name"];
//                    addr.country = [dic stringForKey:@"Country"];
//                    addr.province = [dic stringForKey:@"State"];
//                    addr.city = [dic stringForKey:@"City"];
//                    addr.subLocality = [dic stringForKey:@"SubLocality"];
//                    addr.countryCode = [dic stringForKey:@"CountryCode"];
//
//                    [AFFLModeAddress setCacheAddress:addr];
//
//                    result = YES;
//                }
//
//                block(result, self);
//            }];
        });
    }
}

+ (NSMutableArray*)getCacheArray:(AFFDataPartion*)partion isName:(BOOL)isName {
    if(!isName) return mArrCacheImage;
    
    switch (partion.type) {
        case kPartionTypePlayer:
        case kPartionTypePlayerNickName: {
            if(mArrCacheName==nil)
                mArrCacheName = [NSMutableArray array];
            
            return mArrCacheName;
        }
            
        case kPartionTypePlayerNoteName: {
            if(mArrCacheNameNote==nil)
                mArrCacheNameNote = [NSMutableArray array];
            
            return mArrCacheNameNote;
        }
            
        case kPartionTypePlayerRoomNickName:{
            if(mArrCacheNameNickRoom==nil)
                mArrCacheNameNickRoom = [NSMutableArray array];
            
            return mArrCacheNameNickRoom;
        }
            
        case kPartionTypePlayerRoomWorkerName: {
            if(mArrCacheNameWorker==nil)
                mArrCacheNameWorker = [NSMutableArray array];
            
            return mArrCacheNameWorker;
        }
            
        case kPartionTypeSeal:
        case kPartionTypeEntitySeal: {
            if(mArrCacheSeal ==nil)
                mArrCacheSeal = [NSMutableArray array];
            
            return mArrCacheSeal;
        }
            
        case kPartionTypeSealSigned: {
            if(mArrCacheSealSigned ==nil)
                mArrCacheSealSigned = [NSMutableArray array];
            
            return mArrCacheSealSigned;
        }
            
        default: {
            if(mArrCacheNameRoom==nil)
                mArrCacheNameRoom = [NSMutableArray array];
            
            return mArrCacheNameRoom;
        }
    }
    
    return nil;
}

+ (void)updateCacheData:(U64)code eleCode:(U64)eleCode pType:(AFEPartionType)pType data:(NSObject*)data isName:(BOOL)isName{
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.code = code;
    partion.elementCode = eleCode;
    partion.type = pType;
    
    if(data){
        if(isName){
            partion.textDecode = partion.textShow = (NSString*)data;
        }else {
            partion.dataIcon = (NSData*)data;
        }
    }
    
    [AFFDataText setCacheData:partion isName:isName];
}

+ (void)setCacheData:(AFFDataPartion*)partion isName:(BOOL)isName {
    if(partion==nil || partion.code==0)
        return;
    
    NSMutableArray *mArrCache = [self getCacheArray:partion isName:isName];
    
    @synchronized(mArrCache) {
        NSDictionary *dicr = [self getTargetDic:partion set:YES cacheArr:mArrCache isName:isName]; // 一级dic
        if(isName){
            // 如果名称没有了说明是要去掉缓存
            if([NSString isNilOrEmpty:partion.textDecode]){
                if(dicr) {
                    [mArrCache removeObject:dicr];
                }
                return;
            }
        }else {
            // 如果头像没有了说明是要去掉缓存
            if(partion.dataIcon==nil){
                if(dicr) {
                    [mArrCache removeObject:dicr];
                }
                [partion delIcon];
                return;
            }
            
            partion.hasIcon = [partion saveIcon];
        }
        
        NSDictionary *dic = @{@"value":@{@"pType":@([self getCachePartionType:partion isName:isName]), @"value":isName?partion.textDecode:@(partion.hasIcon), @"ele":@(partion.elementCode)}};
        
        if(dicr){
            [((NSMutableDictionary*)dicr) setObject:dic forKey:@(partion.code)];
        }else {
            [mArrCache addObject:[NSMutableDictionary dictionaryWithObject:dic forKey:@(partion.code)]];
        }
    }
}

+ (void)setCacheData:(NSArray*)arr partion:(AFFDataPartion*)partion {
    if(arr && arr.count>0 && partion && partion.type>kPartionTypeText){
        dispatch_async(kQueueMain, ^{
            NSMutableArray *mArrCache = [self getCacheArray:partion isName:YES];
            @synchronized(mArrCache) {
                // 添加到后面发生的更新就获取不到了，因为遍历从0开始；所以要么更新，要么就插入前面
                //                [mArrCache addObjectsFromArray:arr];
                [mArrCache insertObjects:arr atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, arr.count)]];
            }
        });
    }
}

+ (BOOL)setCacheSealSigns:(NSArray*)signs {
    // 贴章信息是可控变化的，可根据数量检查
    if(signs.count==0 || signs.count==mArrCacheSealSigned.count)return NO;
    
    @synchronized (mArrCacheSealSigned) {
        if(mArrCacheSealSigned==nil)
            mArrCacheSealSigned = [NSMutableArray array];
        
        [mArrCacheSealSigned removeAllObjects];
        [mArrCacheSealSigned addObjectsFromArray:signs];
    }
    
    return YES;
}


// 头像由于不同实体类型可能共用一个，也可能由于代表意义不同要区别
+ (AFEPartionType)getCachePartionType:(AFFDataPartion*)partion isName:(BOOL)isName{
    AFEPartionType eType = partion.type;
    
    if(isName){
        if(eType == kPartionTypePlayer ||
           eType == kPartionTypePlayerNickName){
            eType = kPartionTypePlayer;
        }
        
        return eType;
    }
    
    // 只有人的头像是统一的
    switch (partion.type) {
        case kPartionTypePlayer:
        case kPartionTypePlayerNickName:
        case kPartionTypePlayerNoteName:
        case kPartionTypePlayerRoomNickName:
        case kPartionTypePlayerRoomWorkerName:
        case kPartionTypeResident: {
            eType = kPartionTypePlayer;
        } break;
            
        default:
            break;
    }
    
    return eType;
}

// 获取缓存配置对象
+ (NSDictionary *)getTargetDic:(AFFDataPartion*)partion set:(BOOL)set cacheArr:(NSArray*)cacheArr isName:(BOOL)isName{
    NSDictionary *dicr = nil; // 一级dic
    @synchronized(cacheArr) {
        for(NSMutableDictionary *dic in cacheArr){
            U64 key = [[[dic allKeys] firstObject] longLongValue];
            if(partion.code!=key)
                continue;
            
            NSDictionary *div = [dic dictionaryForKey:@(key)];
            NSDictionary *dicE = [div dictionaryForKey:@"value"];
            AFEPartionType pType = (AFEPartionType)[dicE int32ForKey:@"pType"];
            U64 eleCode = [dicE int64ForKey:@"ele"];
            AFEPartionType eType = [self getCachePartionType:partion isName:isName];
            
            if(partion.code == key && eType == pType){
                if(isName && eleCode != partion.elementCode)
                    continue;
                
                dicr = set?dic:dicE;
                break;
            }
        }
    }
    
    return dicr;
}



// 清理缓存
+ (void)cleanCache:(AFEPartionType)pType code:(U64)code eleCode:(U64)eleCode isName:(BOOL)isName {
    AFFDataPartion *partion = [[AFFDataPartion alloc] init];
    partion.code = code;
    partion.type = pType;
    partion.elementCode = eleCode;
    
    NSMutableArray *arr = [self getCacheArray:partion isName:isName];
    
    @synchronized (arr) {
        NSMutableArray *mArrDel = [NSMutableArray array];
        
        for(NSDictionary *dic in arr){
            U64 key = [[[dic allKeys] firstObject] longLongValue];
            
            NSDictionary *div = [dic dictionaryForKey:@(key)];
            NSDictionary *dicE = [div dictionaryForKey:@"value"];
            AFEPartionType pType = (AFEPartionType)[dicE int32ForKey:@"pType"];
            U64 eleCode = [dicE int64ForKey:@"ele"];
            AFEPartionType eType = [self getCachePartionType:partion isName:isName];
            
            if(eType != pType)
                continue;
            
            // 有code
            if(partion.code>0){
                if(partion.code == key){
                    if(partion.elementCode>0){
                        if(partion.elementCode==eleCode){
                            goto bbk;
                            break;
                        }
                        
                        continue;
                    }
                    
                    goto bbk;
                }
                
                continue;
            }
            
            if(partion.elementCode>0){
                if(partion.elementCode==eleCode){
                    goto bbk;
                }
                
                continue;
            }
            
            
        bbk:
            [mArrDel addObject:dic];
            
        }
        
        for(NSDictionary *dic in mArrDel){
            [arr removeObject:dic];
        }
        
        if(mArrDel.count>0 && !isName){
            [partion delIcon];
        }
    }
}

+ (void)cleanSelf {
    [mArrCacheImage removeAllObjects];
    [mArrCacheName removeAllObjects];
    [mArrCacheNameNote removeAllObjects];
    [mArrCacheNameNickRoom removeAllObjects];
    [mArrCacheNameWorker removeAllObjects];
    [mArrCacheNameRoom removeAllObjects];
    [mArrCacheSeal removeAllObjects];
    [mArrCacheSealSigned removeAllObjects];
}

@end
